/****

    activequant - activestocks.eu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

	
	contact  : contact@activestocks.eu
    homepage : http://www.activestocks.eu

****/
package org.activequant.util.charting;

import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.data.general.Series;
import org.jfree.data.xy.XYDataItem;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/**
 * XYCombinedChart extends CombinedDomainChartBase&lt;Double&gt;.<br/>
 * Holds the following associated variables:
 * <ul>
 * <li>windowSize(double)</li>
 * </ul>
 * Holds the following inherited variables:
 * <ul>
 * <li>plot(CombinedDomainXYPlot)</li>
 * <li>chart(JFreeChart)</li>
 * <li>frame(JFrame)</li>
 * <li>seriesList(List&lt;Series&gt;)</li>
 * <li>latestX(AtomicReference&lt;T&gt;)</li>
 * <li>isCleanupScheduled(AtomicBoolean)</li>
 * </ul>
 * @author Dimitar
 *
 */
public class XYCombinedChart extends CombinedDomainChartBase<Double> {
	/**
	 * private double windowSize = Double.MAX_VALUE
	 */
	private double windowSize = Double.MAX_VALUE;
	/**
	 * Sets the associated windowSize(double) with the given val(Double)
	 * @param val
	 */
	public void setWindowSize(Double val) {
		windowSize = val;
	}
	/**
	 * Creates and returns a NumberAxis using the given xTitle(String) which isn't forced to include 0.
	 * @param xTitle
	 * @return
	 */
	private static ValueAxis createXAxis(String xTitle) {
		NumberAxis axis = new NumberAxis(xTitle);
		axis.setAutoRangeIncludesZero(false);
		return axis;
	}
	/**
	 * Constructs an XYCombinedChart(extends CombinedDomainChartBase&lt;Double&gt;) using the given frameTitle(String) and xTitle(String):<br/>
	 * - creates a xAxis(NumberAxis) using the given xTitle(String) which isn't forced to include 0.<br/>
	 * - initializes its inherited plot(CombinedDomainXYPlot) with a new CombinedDomainXYPlot using that xAxis(NumberAxis) (also a ValueAxis) as its shared axis.<br/>
	 * - initializes its inherited chart(JFreeChart) with a new JFreeChart based on its inherited plot(CombinedDomainXYPlot).<br/>
	 * - initializes its inherited frame(JFrame) with a new ChartFrame using the given frameTitle(String) as its title and holding its inherited chart(JFreeChart).
	 * @param frameTitle
	 * @param xTitle
	 */
	public XYCombinedChart(String frameTitle, String xTitle) {
		super(frameTitle, createXAxis(xTitle));
	}
	/**
	 * Creates a new XYDataItem using the given x(Double) and y(double) and adds it to the given series(Series) (an XYSeries)
	 */
	@Override
	protected void addToSeries(Series series, Double x, double y) {
		((XYSeries) series).add(new XYDataItem(x.doubleValue(), y));
	}
	/**
	 * Removes a range of XYDataItems from the given series(Series) (an XYSeries) who are no longer visible according to the associated windowSize(double)
	 * if the max/latest visible x-value is the given max(Double)
	 */
	@Override
	protected void cleanSeries(Series series, Double max) {
		double min = max.doubleValue() - windowSize;
		XYSeries xySeries = (XYSeries) series;
		int size = xySeries.getItemCount();
		int delIndex = -1;
		for(int i = 0; i < size; i++) {
			double x = xySeries.getX(i).doubleValue();
			if(x < min) {
				delIndex = i;
			}
		}
		
		if(delIndex > 0) {
			xySeries.delete(0, delIndex);
		}
	}
	/**
	 * Creates and returns an empty XYSeriesCollection dataset
	 */
	@Override
	protected XYSeriesCollection createDataset() {
		return new XYSeriesCollection();
	}
	/**
	 * Creates and returns a series(XYSeries) with the given legend(String). It also adds the series(XYSeries) to the given dataset(XYDataset) (an XYSeriesCollection)
	 */
	@Override
	protected Series createSeries(XYDataset dataset, String legend) {
		XYSeries series = new XYSeries(legend);
		((XYSeriesCollection) dataset).addSeries(series);
		return series;
	}
}
